/*
 * @(#)Patient.java
 * Date 2013-08-08
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.model.patient;

import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import org.joda.time.DateTime;

import us.hornerscorners.lamppost.model.DateJsonDeserializer;
import us.hornerscorners.lamppost.model.DateJsonSerializer;

import us.hornerscorners.lamppost.model.common.AbstractPersistableModel;
import us.hornerscorners.lamppost.model.common.CodedElement;
import us.hornerscorners.lamppost.model.common.EmailAddress;
import us.hornerscorners.lamppost.model.common.InstanceIdentifier;
import us.hornerscorners.lamppost.model.common.PersistableModelType;
import us.hornerscorners.lamppost.model.common.PhoneNumber;


/**
 *
 * @author jim
 *
 * See page 175 Rev 9.0 ITI-Vol2b
 *
 * SeeAlso
 *  PRPAMT201301UV02Patient
 *
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Patient extends AbstractPersistableModel {

    /** Field description */
    @JsonSerialize(using = DateJsonSerializer.class)
    @JsonDeserialize(using = DateJsonDeserializer.class)
    private DateTime birthDate;

    /** Field description */
    private BirthPlace birthPlace;

    /** Field description */
    private final List<Citizenship> citizenships;

    /** Field description */
    private final List<CodedElement> confidentialityCodes;

    /** Field description */
    @JsonSerialize(using = DateJsonSerializer.class)
    @JsonDeserialize(using = DateJsonDeserializer.class)
    private DateTime deceasedDate;

    /** Field description */
    private Boolean deceasedInd;

    /** Field description */
    private final List<EmailAddress> emailAddresses;

    /** Field description */
    private final List<Employment> employments;

    /** Field description */
    private final List<CodedElement> ethnicGroups;

    /** Field description */
    private CodedElement gender;

    /** Field description */
    private final List<InstanceIdentifier> identifiers;

    /** Field description */
    private final List<LanguageCommunication> languagesSpoken;

    /** Field description */
    private CodedElement maritalStatusCode;

    /** Field description */
    private Boolean multipleBirthInd;

    /** Field description */
    private Integer multipleBirthOrderNumber;

    /** Field description */
    private final List<OtherIdentifier> otherIds;

    /** Field description */
    private final List<PersonName> personNames;

    /** Field description */
    private final List<PersonalRelationship> personalRelationships;

    /** Field description */
    private final List<PhoneNumber> phoneNumbers;

    /** Field description */
    private final List<PostalAddress> postalAddresses;

    /** Field description */
    private ContactOrganization providerOrganization;

    /** Field description */
    private final List<CodedElement> raceCodes;

    /** Field description */
    private CodedElement religiousAffiliationCode;

    /** Field description */
    private CodedElement statusCode;

    /**
     * Constructs ...
     *
     */
    public Patient() {

        super(PersistableModelType.Patient);

        this.identifiers = new ArrayList<>();
        this.emailAddresses = new ArrayList<>();
        this.confidentialityCodes = new ArrayList<>();
        this.citizenships = new ArrayList<>();
        this.employments = new ArrayList<>();
        this.languagesSpoken = new ArrayList<>();
        this.otherIds = new ArrayList<>();
        this.personNames = new ArrayList<>();
        this.personalRelationships = new ArrayList<>();
        this.raceCodes = new ArrayList<>();
        this.ethnicGroups = new ArrayList<>();
        this.phoneNumbers = new ArrayList<>();
        this.postalAddresses = new ArrayList<>();
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public DateTime getBirthDate() {
        return birthDate;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public BirthPlace getBirthPlace() {
        return birthPlace;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<Citizenship> getCitizenships() {
        return citizenships;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<CodedElement> getConfidentialityCodes() {
        return confidentialityCodes;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public DateTime getDeceasedDate() {
        return deceasedDate;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public Boolean getDeceasedInd() {
        return deceasedInd;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<EmailAddress> getEmailAddresses() {
        return emailAddresses;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<Employment> getEmployments() {
        return employments;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<CodedElement> getEthnicGroups() {
        return ethnicGroups;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public CodedElement getGender() {
        return gender;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<InstanceIdentifier> getIdentifiers() {
        return identifiers;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<LanguageCommunication> getLanguagesSpoken() {
        return languagesSpoken;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public CodedElement getMaritalStatusCode() {
        return maritalStatusCode;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public Boolean getMultipleBirthInd() {
        return multipleBirthInd;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public Integer getMultipleBirthOrderNumber() {
        return multipleBirthOrderNumber;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<OtherIdentifier> getOtherIds() {
        return otherIds;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<PersonName> getPersonNames() {
        return personNames;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<PersonalRelationship> getPersonalRelationships() {
        return personalRelationships;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<PhoneNumber> getPhoneNumbers() {
        return phoneNumbers;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<PostalAddress> getPostalAddresses() {
        return postalAddresses;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public ContactOrganization getProviderOrganization() {
        return providerOrganization;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<CodedElement> getRaceCodes() {
        return raceCodes;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public CodedElement getReligiousAffiliationCode() {
        return religiousAffiliationCode;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public CodedElement getStatusCode() {
        return statusCode;
    }

    /**
     * Method description
     *
     *
     * @param birthDate
     */
    public void setBirthDate(DateTime birthDate) {

        if (birthDate != null) {
            this.birthDate = birthDate.withTimeAtStartOfDay();
        } else {
            this.birthDate = null;
        }
    }

    /**
     * Method description
     *
     *
     * @param birthPlace
     */
    public void setBirthPlace(BirthPlace birthPlace) {
        this.birthPlace = birthPlace;
    }

    /**
     * Method description
     *
     *
     * @param deceasedDate
     */
    public void setDeceasedDate(DateTime deceasedDate) {

        if (deceasedDate != null) {
            this.deceasedDate = deceasedDate.withTimeAtStartOfDay();
        } else {
            this.deceasedDate = null;
        }
    }

    /**
     * Method description
     *
     *
     * @param deceasedInd
     */
    public void setDeceasedInd(Boolean deceasedInd) {
        this.deceasedInd = deceasedInd;
    }

    /**
     * Method description
     *
     *
     * @param gender
     */
    public void setGender(CodedElement gender) {
        this.gender = gender;
    }

    /**
     * Method description
     *
     *
     * @param maritalStatusCode
     */
    public void setMaritalStatusCode(CodedElement maritalStatusCode) {
        this.maritalStatusCode = maritalStatusCode;
    }

    /**
     * Method description
     *
     *
     * @param multipleBirthInd
     */
    public void setMultipleBirthInd(Boolean multipleBirthInd) {
        this.multipleBirthInd = multipleBirthInd;
    }

    /**
     * Method description
     *
     *
     * @param multipleBirthOrderNumber
     */
    public void setMultipleBirthOrderNumber(Integer multipleBirthOrderNumber) {
        this.multipleBirthOrderNumber = multipleBirthOrderNumber;
    }

    /**
     * Method description
     *
     *
     * @param providerOrganization
     */
    public void setProviderOrganization(ContactOrganization providerOrganization) {
        this.providerOrganization = providerOrganization;
    }

    /**
     * Method description
     *
     *
     * @param religiousAffiliationCode
     */
    public void setReligiousAffiliationCode(CodedElement religiousAffiliationCode) {
        this.religiousAffiliationCode = religiousAffiliationCode;
    }

    /**
     * Method description
     *
     *
     * @param statusCode
     */
    public void setStatusCode(CodedElement statusCode) {
        this.statusCode = statusCode;
    }
}
